﻿using RabbitMQ_Service.MessageTypes;
using System;
using System.Collections.Generic;
using System.Configuration;
using Utility.Global.DataTypes;
using Utility.RabbitMQ_Service;
using Utility.RabbitMQ_Service.Implementations;
using Utility.RabbitMQ_Service.MessageTypes;

namespace Application_Core.Dispatcher_Component.Access_Layer.Implementations
{
    public class DispatcherComponentFacade : DispatcherForMonitorService, DispatcherForClientService
    {
        #region ForClient

        public object RequestInvokeMethod(string methodName, String returnTypName, Type[] argTypes, object[] args)
        {
            Object obj = null;

            using (RabbitMQService service = RabbitMQServiceImpl.CreateRabbitMQService())
            {
                MethodRequestMessage request = new MethodRequestMessage
                {
                    MethodName = methodName,
                    ReturnTypeName = returnTypName,
                    ArgTypes = argTypes,
                    Args = args
                };

                using (RabbitMQQueue<MethodRequestMessage> queue = service.NewRabbitMQQueue<MethodRequestMessage>("dispatcher.requests"))
                {
                    String correlationId = Guid.NewGuid().ToString();
                    queue.SetReplyToQueue("dispatcher.responses");
                    queue.SetCorrelationId(correlationId);
                    queue.Send(request);

                    obj = queue.Receive();
                }
            }

            return obj;
        }

        #endregion

        #region ForMonitor
        public IDictionary<String, SystemTyp> FindSystemStatus()
        {
            IDictionary<String, SystemTyp> systeme = new Dictionary<String, SystemTyp>();

            foreach (ConnectionStringSettings css in ConfigurationManager.ConnectionStrings)
            {
                if (css.ProviderName == "MPS")
                {
                    SystemTyp systemTyp = new SystemTyp() { 
                        Name = css.Name, 
                        Status = SystemState.Status.Offline, 
                        AnzahlDisconnected = 0, 
                        AnzahlVerarbeiteteAnfragen = 0, 
                        LetztesIAmAlive = DateTime.Now, 
                        LetztesUpdate = DateTime.Now
                    };
                    systeme.Add(css.Name, systemTyp);
                }
            }

            return systeme;
        }

        public bool StartSystem(String systemName)
        {
            return this.SendStartOrStopMessage(systemName, true);
        }

        public bool StopSystem(String systemName)
        {
            return this.SendStartOrStopMessage(systemName, false);
        }

        #endregion

        private bool SendStartOrStopMessage(String systemName, bool start)
        {
            using (RabbitMQService service = RabbitMQServiceImpl.CreateRabbitMQService())
            {
                using (RabbitMQQueue<StartOrStopMessage> queue = service.NewRabbitMQQueue<StartOrStopMessage>("monitor.startorstop"))
                {
                    StartOrStopMessage stop = new StartOrStopMessage
                    {
                        SystemName = systemName,
                        Start = start
                    };

                    queue.Send(stop);
                }
            }
            return true;
        }
    }
}
